package com.woniuxy.uums.service.impl;

import com.baidu.aip.face.AipFace;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.common.utils.FaceUploadResult;
import com.woniuxy.uums.pojo.FaceInfo;
import com.woniuxy.uums.service.FaceInfoService;
import com.woniuxy.uums.mapper.FaceInfoMapper;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;

import java.util.UUID;

/**
* @author 86159
* @description 针对表【face_info(人脸特征信息表)】的数据库操作Service实现
* @createDate 2025-07-18 15:08:45
*/
@Service
public class FaceInfoServiceImpl extends ServiceImpl<FaceInfoMapper, FaceInfo>
    implements FaceInfoService{


    @Autowired
    private AipFace aipFace;

    @Value("${baidu.face.group-id}")
    private String groupId;

    /**
     * 上传人脸图片到百度云人脸库（优化版）
     * 支持URL和Base64两种方式，自动处理下载失败情况
     *
     * @param imageUrl 图片URL
     * @param userId 用户ID（owner_id）
     * @return FaceUploadResult 包含百度云返回的路径和token
     */
    @Override
    public FaceUploadResult uploadFaceImage(String imageUrl, String userId) {
        try {
            // 1. 首先尝试URL方式上传
            FaceUploadResult urlResult = uploadByUrl(imageUrl, userId);
            if (urlResult.getFaceToken() != null) {
                return urlResult;
            }

            // 2. 如果URL方式失败，尝试下载图片后使用Base64方式上传
            return uploadByBase64(imageUrl, userId);

        } catch (Exception e) {
            return new FaceUploadResult(null, null, "人脸上传失败: " + e.getMessage());
        }
    }

    /**
     * 通过URL方式上传人脸
     */
    private FaceUploadResult uploadByUrl(String imageUrl, String userId) {
        try {
            JSONObject res = aipFace.addUser(
                    imageUrl,
                    "URL",
                    groupId,
                    userId,
                    new HashMap<>()
            );

            return parseBaiduResult(res, imageUrl);
        } catch (Exception e) {
            return new FaceUploadResult(null, null, "URL方式上传失败: " + e.getMessage());
        }
    }

    /**
     * 通过Base64方式上传人脸
     */
    private FaceUploadResult uploadByBase64(String imageUrl, String userId) {
        try {
            byte[] imageData = downloadImageWithRetry(imageUrl, 3);
            String base64Image = Base64Utils.encodeToString(imageData);

            JSONObject res = aipFace.addUser(
                    base64Image,
                    "BASE64",
                    groupId,
                    userId,
                    new HashMap<>()
            );

            // 生成临时路径用于返回
            String tempPath = "downloaded_" + UUID.randomUUID() + ".jpg";
            return parseBaiduResult(res, tempPath);
        } catch (Exception e) {
            return new FaceUploadResult(null, null, "Base64方式上传失败: " + e.getMessage());
        }
    }

    /**
     * 下载图片（带重试机制）
     */
    private byte[] downloadImageWithRetry(String imageUrl, int maxRetries) throws Exception {
        int retryCount = 0;
        Exception lastException = null;

        while (retryCount < maxRetries) {
            try {
                return downloadImage(imageUrl);
            } catch (Exception e) {
                lastException = e;
                retryCount++;
                Thread.sleep(1000 * retryCount); // 指数退避
            }
        }

        throw new Exception("图片下载失败，达到最大重试次数", lastException);
    }

    /**
     * 下载图片
     */
    private byte[] downloadImage(String imageUrl) throws Exception {
        HttpURLConnection connection = (HttpURLConnection) new URL(imageUrl).openConnection();
        connection.setRequestMethod("GET");
        connection.setConnectTimeout(5000);
        connection.setReadTimeout(10000);

        try (InputStream in = connection.getInputStream();
             ByteArrayOutputStream out = new ByteArrayOutputStream()) {

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                out.write(buffer, 0, bytesRead);
            }

            return out.toByteArray();
        }
    }

    /**
     * 解析百度云返回结果
     */
    private FaceUploadResult parseBaiduResult(JSONObject res, String imagePath) {
        if (res.getInt("error_code") == 0) {
            JSONObject result = res.getJSONObject("result");
            String faceToken = result.getString("face_token");
            return new FaceUploadResult(imagePath, faceToken, "上传成功");
        } else {
            String errorMsg = "百度云错误: " + res.getInt("error_code") + " - " + res.getString("error_msg");
            return new FaceUploadResult(null, null, errorMsg);
        }
    }
}




